package ws

import (
	"bytes"
	"dgo/MyProj/PrjRPC"
	"dgo/goutils/utils"
	"golang.org/x/net/websocket"
	"net/http"
	"strings"
)

var (
	buf_spliter = []byte{0x0A}
)

type RPCWsSvrEngine struct {
	rpc *PrjRPC.RPC
}

func (this *RPCWsSvrEngine) OnWsConn(ws *websocket.Conn) {
	wsconn := NewWsConnWrapper(ws)
	for {
		msgtype, msg, err := ReceiveMessage(ws)
		if err != nil {
			utils.Log.DebugTypef("rpc", "接收消息出现异常:%s", err.Error())
			break
		}
		this.OnWsBaseCmdRecv(wsconn, int(msgtype), msg)

	}

}

func (this *RPCWsSvrEngine) SetRPC(rpc *PrjRPC.RPC) {
	this.rpc = rpc
}

func (this *RPCWsSvrEngine) OnWsBaseConnClose(wsconn *WsConnWrapper) {
	if wsconn.TagPtr != nil {
		cmd_rec := wsconn.TagPtr.(*PrjRPC.RPCCmdRec)
		cmd_rec.NullSendFunc()
	}
}

func (this *RPCWsSvrEngine) OnWsBaseCmdRecv(wsconn *WsConnWrapper, msgtype int, msg []byte) {
	if wsconn.TagPtr == nil {
		// id;
		cmdstr := string(msg)
		if len(cmdstr) < 3 || len(cmdstr) > 50 {
			wsconn.SendMsg("0;503 inner error")
			return
		}
		cmd_rec := this.rpc.CheckGetCmdRec(cmdstr)
		cmd_rec.SendFuncAssign(func(data []byte) error {
			return wsconn.SendMsg(data)
		})
		wsconn.TagPtr = cmd_rec
	}

	cmd_rec := wsconn.TagPtr.(*PrjRPC.RPCCmdRec)
	if msgtype == 1 {
		str := string(msg)
		strs := strings.SplitN(str, ",", 2)
		if len(strs) == 1 {
			this.rpc.Invoke_rp_func(cmd_rec, strs[0], "")
		} else {
			this.rpc.Invoke_rp_func(cmd_rec, strs[0], strs[1])
		}
	} else { // BinaryMessage
		nbuf := bytes.SplitN(msg, buf_spliter, 2)
		id := string(nbuf[0])
		if len(nbuf) > 1 {
			this.rpc.Invoke_rp_func(cmd_rec, id, nbuf[1])
		} else {
			this.rpc.Invoke_rp_func(cmd_rec, id, "")
		}
	}
}

func StartRpcSvrWithWsService(ws_req_uri string) *RPCWsSvrEngine {
	rval := &RPCWsSvrEngine{}
	http.Handle(ws_req_uri, websocket.Handler(rval.OnWsConn))
	return rval
}
